import os
import django
from django.apps import apps
import openpyxl
from openpyxl import Workbook
from openpyxl.styles import Font, Alignment, Border, Side, PatternFill
from openpyxl.utils import get_column_letter

# 设置Django环境
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'house_crm.settings')
django.setup()


def extract_django_model_fields(app_label, model_name):
    """
    提取Django模型的字段信息

    参数:
    app_label: Django应用标签
    model_name: 模型类名

    返回:
    包含字段名和中文名的列表，格式为[(field_name, verbose_name), ...]
    """
    try:
        model = apps.get_model(app_label, model_name)
        fields = []
        
        for field in model._meta.fields:
            field_name = field.name
            verbose_name = getattr(field, 'verbose_name', field_name)
            fields.append((field_name, str(verbose_name)))
        
        return fields
    except LookupError:
        print(f"错误：找不到模型 {app_label}.{model_name}")
        return []
    except Exception as e:
        print(f"错误：{e}")
        return []


def extract_all_django_models(app_label):
    """
    提取指定Django应用中的所有模型

    参数:
    app_label: Django应用标签

    返回:
    字典，键为模型名，值为字段列表
    """
    try:
        models_dict = {}
        # 获取指定应用的所有模型
        for model in apps.get_app_config(app_label).get_models():
            fields = []
            for field in model._meta.fields:
                field_name = field.name
                verbose_name = getattr(field, 'verbose_name', field_name)
                fields.append((field_name, str(verbose_name)))
            
            if fields:
                models_dict[model.__name__] = fields
        
        return models_dict
    except LookupError:
        print(f"错误：找不到应用 {app_label}")
        return {}
    except Exception as e:
        print(f"错误：{e}")
        return {}


def write_to_excel(models_fields, output_file):
    """
    将字段信息写入Excel文件，每个模型一个工作表

    参数:
    models_fields: 包含模型名和字段信息的字典
    output_file: 输出的Excel文件路径
    """
    # 创建新的工作簿
    wb = Workbook()
    
    # 删除默认创建的工作表
    if 'Sheet' in wb.sheetnames:
        wb.remove(wb['Sheet'])
    
    # 定义样式
    header_font = Font(bold=True, color="FFFFFF", size=12)
    header_fill = PatternFill(start_color="366092", end_color="366092", fill_type="solid")
    header_alignment = Alignment(horizontal="center", vertical="center", wrap_text=True)
    data_alignment = Alignment(horizontal="left", vertical="center", wrap_text=True)
    border = Border(
        left=Side(style='thin'),
        right=Side(style='thin'),
        top=Side(style='thin'),
        bottom=Side(style='thin')
    )
    
    # 为每个模型创建一个工作表
    for model_name, fields in models_fields.items():
        # 创建工作表
        sheet_name = model_name[:31]  # Excel限制工作表名称长度
        ws = wb.create_sheet(sheet_name)
        
        # 添加模型名称标题
        ws['B1'] = f"模型: {model_name}"
        title_cell = ws['B1']
        title_cell.font = Font(bold=True, size=14, color="366092")
        title_cell.alignment = Alignment(horizontal="center")
        
        # 添加表头
        ws['B2'] = "字段名"
        ws['B3'] = "中文名"
        
        # 应用表头样式
        for row in [2, 3]:
            cell = ws[f'B{row}']
            cell.font = header_font
            cell.fill = header_fill
            cell.alignment = header_alignment
            cell.border = border
        
        # 写入数据（从C列开始）
        for col_idx, (field_name, verbose_name) in enumerate(fields, start=3):
            col_letter = get_column_letter(col_idx)
            
            # 写入英文名（第2行）
            ws[f'{col_letter}2'] = field_name
            cell = ws[f'{col_letter}2']
            cell.border = border
            cell.alignment = data_alignment
            
            # 写入中文名（第3行）
            ws[f'{col_letter}3'] = verbose_name
            cell = ws[f'{col_letter}3']
            cell.border = border
            cell.alignment = data_alignment
        
        # 添加5行空行（从第4行开始）
        for row in range(4, 9):
            for col in range(2, len(fields) + 3):  # 从B列到最后一个字段列
                col_letter = get_column_letter(col)
                cell = ws[f'{col_letter}{row}']
                cell.border = border
        
        # 自动调整列宽
        adjust_column_width(ws)
        
        print(f"已处理模型: {model_name}，共 {len(fields)} 个字段")
    
    # 保存文件
    wb.save(output_file)
    print(f"\n数据已写入 {output_file}，共处理了 {len(models_fields)} 个模型")


def adjust_column_width(ws):
    """
    自动调整列宽以适应内容
    """
    for column in ws.columns:
        max_length = 0
        column_letter = get_column_letter(column[0].column)
        for cell in column:
            try:
                if cell.value and len(str(cell.value)) > max_length:
                    max_length = len(str(cell.value))
            except:
                pass
        adjusted_width = min(max_length + 2, 30)  # 限制最大宽度
        ws.column_dimensions[column_letter].width = adjusted_width


# 使用示例
if __name__ == "__main__":
    # 替换为你的Django应用标签
    app_label = "house"  # 您的Django应用名称
    
    # 输出的Excel文件路径
    output_file = "django_model_fields.xlsx"
    
    # 提取所有模型的字段信息
    models_fields = extract_all_django_models(app_label)
    
    # 如果没有找到任何模型，打印警告
    if not models_fields:
        print(f"警告：在应用 '{app_label}' 中没有找到任何模型")
        print("请检查：")
        print("1. Django项目设置是否正确")
        print("2. 应用标签是否正确")
        print("3. 模型是否正确定义")
    else:
        # 打印找到的模型
        print(f"在应用 '{app_label}' 中找到 {len(models_fields)} 个模型:")
        for model_name in models_fields.keys():
            print(f"  - {model_name}")
        
        # 写入Excel
        write_to_excel(models_fields, output_file)